-- Viral Resistance - T-Engine 4 Module
-- Copyright (C) 2010 Mikolai Fajer
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
--
-- Mikolai Fajer "yufra"
-- mfajer@gmail.com

local DamageType = require("engine.DamageType")
local Map = require "engine.Map"
local Dialog = require "engine.Dialog"

name = "Power Loss"
desc = function(self, who)
	local desc = {}
	if self:isCompleted("investigate") then
		desc[#desc+1] = "#LIGHT_GREEN#* The generator panel showed a problem with the power conduits."
	elseif self:isStatus(engine.Quest.PENDING, "investigate") then
		desc[#desc+1] = "#SLATE#* You do not know what caused the power loss."
	end
	if self:isCompleted("find_broken_conduits") then
		desc[#desc+1] = "#LIGHT_GREEN#* You found the broken power conduit."
	elseif self:isStatus(engine.Quest.PENDING, "find_broken_conduits") then
		desc[#desc+1] = "#SLATE#* You need to find the problem with the power conduits."
	end
	if self:isCompleted("flip_the_switch") then
		desc[#desc+1] = "#LIGHT_GREEN#* The power is back on!"
	elseif self:isStatus(engine.Quest.PENDING, "flip_the_switch") then
		desc[#desc+1] = "#SLATE#* Return to the generator panel and flip the switch."
	end
	return table.concat(desc, "\n")
end
num_broken_conduits = 3

setup = function(self, who)
	-- Force the map to update
	-- NOT WORKING... takes a turn to update right now
	self:turn_off_lights()
	game.player:playerFOV()
	game.level.map:redisplay()
	-- Add the zombies throughout the floor
	local check = function(tx, ty)
		return true
	end
	local apply = function(tx, ty)
		local actor = game.level.map(tx, ty, Map.ACTOR)
		if actor and not actor.unique and rng.percent(50) then
			actor:takeVloadHit(actor.max_vload, {name="Viral contamination"})
		end
	end
	game:floodFill(who.x, who.y, check, apply)
	-- Open ward doors
	self:unlock_inner_ward()
	self:unlock_outer_ward()
	-- And the dialog
	Dialog:simpleLongPopup("Lights Out!", [[#LIGHT_GREEN#The lights flicker a few times and then cut out.  The hum of electricity ever-present in the hospital disappears along with it, but a second later the emergency lights along the walls come to life.  In the distance screams can be heard, first of surprise and then turning into terror.]], game.h * 0.6)
end

unlock_outer_ward = function(self, who)
	for i, v in pairs(game.level.spots) do
		if v.type == "biohazard doors" and v.subtype == "outer" then
			local current_door = game.level.map(v.x, v.y, Map.TERRAIN)
			if current_door.door_unlocked then
				local opened = game.zone:makeEntityByName(game.level, 'terrain', current_door.door_unlocked)
				game.zone:addEntity(game.level, opened, "terrain", v.x, v.y)
			end
		end
	end
end

unlock_inner_ward = function(self, who)
	for i, v in pairs(game.level.spots) do
		if v.type == "biohazard doors" and v.subtype == "inner" then
			local current_door = game.level.map(v.x, v.y, Map.TERRAIN)
			if current_door.door_unlocked then
				local opened = game.zone:makeEntityByName(game.level, 'terrain', current_door.door_unlocked)
				game.zone:addEntity(game.level, opened, "terrain", v.x, v.y)
			end
		end
	end
end

-- Called by the level's post_process function
add_broken_conduits = function(self, level)
	local conduit_positions = {}
	local terrain
	for x=0,level.map.w-1 do for y=0,level.map.h-1 do
		terrain = level.map(x, y, engine.Map.TERRAIN)
		if terrain.name == "power conduit" then
			table.insert(conduit_positions, {x=x, y=y})
		end
	end end
	local pos
	for i=1,self.num_broken_conduits do
		pos = rng.tableRemove(conduit_positions)
		terrain = game.zone:makeEntityByName(level, "terrain", "CONDUIT_BROKEN")
		terrain.old_terrain = level.map(pos.x, pos.y, engine.Map.TERRAIN)
		game.zone:addEntity(level, terrain, "terrain", pos.x, pos.y)
		table.insert(level.spots, {x=pos.x, y=pos.y, type="quest", subtype="broken_conduit"})
	end
end

repair_conduit = function(self, who)
	local terrain = game.level.map(who.x, who.y, engine.Map.TERRAIN)
	if terrain.damage then
		terrain.damage = terrain.damage - 1
		print("[[DEBUG]] terrain repaired, current damage :==: ", terrain.damage)
		if terrain.damage <= 0 then
			game.zone:addEntity(game.level, terrain.old_terrain, "terrain", who.x, who.y)
			local spot_id
			for i, spot in ipairs(game.level.spots) do
				if spot.type == 'quest' and spot.subtype == "broken_conduit" and who.x == spot.x and who.y == spot.y then
					spot_id = i
				end
			end
			table.remove(game.level.spots, spot_id)
			game.logSeen(who, ([[%s shouts "All done here."]]):format(who.name))
			-- Update the quest
			self.num_broken_conduits = self.num_broken_conduits - 1
			if self.num_broken_conduits <= 0 then
				self:setStatus(engine.Quest.COMPLETED, "find_broken_conduitss", game.player)
				self:setStatus(engine.Quest.PENDING, "flip_the_switch", game.player)
			end
		end
	end
end

turn_off_lights = function(self)
	-- Wipe out all of the lighting
	for x=0,game.level.map.w-1 do for y=0,game.level.map.h-1 do
		game.level.map.seens(x, y, false)
		game.level.map.remembers(x, y, false)
		game.level.map.lites(x, y, false)
	end end
	game.zone.all_lited = false
	-- Replace with fixed emergency light sources
	for i, v in pairs(game.level.spots) do
		if v.type == "light" and v.subtype == "emergency" then
			local light = game.level.map(v.x, v.y, Map.ACTOR)
			if light then
				light:activate()
			end
		end
	end
end

turn_on_lights = function(self)
	for x=0,game.level.map.w-1 do for y=0,game.level.map.h-1 do
		game.level.map.lites(x, y, true)
	end end
	game.zone.all_lited = true
	-- Replace with fixed emergency light sources
	for i, v in pairs(game.level.spots) do
		if v.type == "light" and v.subtype == "emergency" then
			local light = game.level.map(v.x, v.y, Map.ACTOR)
			if light then
				light:deactivate()
			end
		end
	end
end